import React, { PureComponent, Fragment } from 'react'
import classnames from 'classnames'
import Styles from './index.less'
const form = function(pointer){
    let registedProp = {}
    let cacheCheck = {}
    const strategies = [
        function emailCheck(rules) {
            if (rules.type && rules.type === 'email') {
                let reg = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
                return (value) => {
                    if (!reg.test(value)) {
                        return rules.message
                    }
                    return false
                }
            }
            return false
        },
        function isRequiredCheck(rules) {
            if (rules.required && rules.required === true) {
                return (value) => {
                    if (value === '') {
                        return rules.message
                    }
                    return false
                }
            }
            return false
        },
        function mobileCheck(rules) {
            if (rules.type && rules.type === 'tel') {
                let reg = /(^1[3|5|8][0-9]{9}$)/
                return (value) => {
                    if (!reg.test(value)) {
                        return rules.message
                    }
                    return false
                }
            }
        },
        function customValidate(rules) {
            if (rules.validator && typeof rules.validator === "function") {
                let message;
                function callback(errMsg) {
                    if (errMsg) message = errMsg
                    else message = ''
                }
                return (value) => {
                    rules.validator(rules, value, callback)
                    return message
                }
            }
        }
    ]
    function cacheRuleCreator(ruleList) {
        return value => {
            for (let i = 0, rule; rule = ruleList[i++];) {
                let result = rule(value)
                if (result) {
                    return result
                }
            }
            return ''
        }
    }
    function checkRuleIterator() {
        this.ruleList = []
        this._rules = []
    }
    function validateField(name, value) {
        let newMsg = cacheCheck[name](value)
        let errorMsg = pointer.state[name]
        if (newMsg!== errorMsg) {
            errorMsg = newMsg
            pointer.setState({errorMsgs: {...pointer.state.errorMsgs, [name]: errorMsg}})
        }
    }
    checkRuleIterator.prototype.add = function() {
        this.ruleList = [...this.ruleList, ...arguments]
    }
    checkRuleIterator.prototype.start = function() {
        this._rules = []
        let pointer = Array.prototype.shift.call(arguments)
        let rules = arguments[0]
        for (let i = 0, rule; rule = rules[i++];) {
            for (let j = 0, fn; fn = this.ruleList[j++];) {
                let isConforming = fn.call(pointer, rule)
                if (isConforming) {
                    this._rules.push(isConforming)
                    break; 
                }
            }
        }
        return cacheRuleCreator(this._rules)
    }
    let iterator = new checkRuleIterator()
    iterator.add(...strategies)
    return {
        getFieldDecorator(name, {rules}) {
            if (rules && !cacheCheck[name]) {
                cacheCheck[name] = iterator.start(this, rules)
                registedProp[name] = ''
                // pointer.setState({errorMsgs: {...pointer.state.errorMsgs, [name]: ''}})
            }
            // registedProp = {...registedProp, [name]: ''}
            return node => {
                return React.cloneElement(node, {
                    onChange: (e) => {
                        let value = e.target.value
                        node.props.onChange && node.props.onChange === "function" && node.props.onChange()
                        registedProp = {...registedProp, [name]: value}
                        if (rules) {
                            validateField(name, value)
                        }  
                    },
                    errorMsg: pointer.state.errorMsgs[name]
                })
            } 
        },
        getFieldsValue(key) {
            if (key) {
                return registedProp[key]
            }
            return registedProp
        },
        validateFields(cb) {
            let errorMsgs = {}
            let allChecked = true 
            for (let key in registedProp) {
                let errorMsg = cacheCheck[key](registedProp[key])
                errorMsgs[key] = errorMsg
                if (errorMsg) allChecked = false
            }
            pointer.setState({errorMsgs})
            if (allChecked) {
                cb(null, registedProp)
            } else {
                cb(errorMsgs, registedProp)
            }
        },
    }
}
export class Form extends PureComponent {
    constructor() {
        super()
    }
    static create() {
        return (WrappedComponent) => class Hoc extends PureComponent {
            static displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'
            constructor(props) {
                super(props)
                this.form = form(this)
                this.state = {
                    errorMsgs: {},
                }
            }
            render() {
                const props = {...this.props, form: this.form}
                return (
                    <WrappedComponent {...props}/>
                )
            }
        }
    }
    static Item(props) {
        return props.children
    }
    render() {
        const { className, children } = this.props
        return (
            <div className={className}>
                {React.Children.map(children, (v) => v)}
            </div>
        )
    }
}
export class Input extends PureComponent {
    constructor() {
        super()
    }
    render() {
        const { errorMsg, ...props } = this.props
        return (
            <div className={classnames({[Styles['input-wL']]: true, [Styles.isErr]: !!errorMsg})}>
               <input {...props}/>
               <p>{errorMsg}</p>
            </div>
        )
    }
}
export class Button extends PureComponent {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <button onClick={this.props.onClick} className={Styles['btn-default']}>
                {this.props.children}
            </button>
        )
    }
}

